package cn.mengfly.product.service;

import cn.mengfly.product.api.UserDto;
import cn.mengfly.product.service.fallback.UserRemoteServiceFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

/**
 * 使用 FeignClient 注解
 * <p>
 * 在应用启动时Feign就会使用动态代码机制根据我们所定义的用户服务接口生成相应的类实例，并注入到Spring的应用上下文中
 * <p>
 * USERSERVICE 为要调用的微服务名称
 * <p>
 * 使用 Hystrix 来保护的是消费者服务，因此这里添加到UserService这里，提供服务访问保护
 * <p>
 * 有两种方式去实现访问容错：
 * <p>
 * 1. 在方法上使用 @HystrixCommand 注解的方式
 * <p>
 * 2. 在使用Feign的情况下，添加 fallback 可以指定fallback类，
 * 这时候还需要在配置文件中添加 feign.hystrix.enabled=true 来开启Feign的Hystrix容错功能
 *
 * @author Mengfly
 * @date 2021/3/10 22:05
 */
@FeignClient(value = "USERSERVICE", fallback = UserRemoteServiceFallback.class)
public interface UserRemoteService {

    /**
     * 使用 HystrixCommand 来指定为访问接口添加容错保护，fallbackMethod 用来指定访问失败时的调用方法
     * 这种方式需要有实现类，并保证fallbackMethod方法和请求方法在同一个类中，并且保证方法签名是相同的
     * <p>
     * CacheResult 标识需要将返回结果缓存
     * <p>
     * CacheKey  用来标记如何构建缓存的值
     * <p>
     * CacheRemove 用来标记在方法执行完毕后清除指定的缓存
     * <p>
     * HystrixCollapser 表示使用请求合并
     */
    @RequestMapping(value = "/users", method = RequestMethod.GET)
//    @CacheResult
//    @CacheRemove()
//    @HystrixCommand(fallbackMethod = "findAllFallback")
    List<UserDto> findAll();

    @RequestMapping(value = "/users/{id}", method = RequestMethod.GET)
//    @HystrixCommand(fallbackMethod = "loadFallback")
//    @HystrixCollapser(batchMethod = "findAll")
    UserDto load(@PathVariable("id") Long id);

}
